from turtle import st
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime, timedelta


# 设置中文字体
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
plt.rcParams["axes.unicode_minus"] = False  # 解决负号显示问题

# 页面设置
st.set_page_config(
    page_title="人寿保险业务高级看板",
    page_icon="📊",
    layout="wide",
    initial_sidebar_state="expanded"
)

# 标题
st.title("人寿保险业务高级看板")

# 侧边栏 - 筛选器
with st.sidebar:
    st.header("筛选条件")

    # 时间范围选择
    time_periods = {
        "最近3个月": 3,
        "最近6个月": 6,
        "最近12个月": 12,
        "最近24个月": 24
    }
    selected_period = st.selectbox("时间范围", list(time_periods.keys()))
    months = time_periods[selected_period]

    # 业务类型选择
    business_types = ["全部", "个人寿险", "团体寿险", "健康险", "意外险"]
    selected_business = st.selectbox("业务类型", business_types)

    # 再保人角色选择
    reinsurance_roles = ["全部", "首席再保人", "非首席再保人"]
    selected_role = st.selectbox("再保人角色", reinsurance_roles)

    # 刷新数据按钮
    if st.button("刷新数据"):
        st.session_state.data_updated = True


# 模拟数据生成
@st.cache_data
def generate_insurance_data(months=12):
    # 设置随机种子以确保结果可重现
    np.random.seed(42)

    # 生成时间序列
    dates = pd.date_range(end=datetime.now(), periods=months, freq='MS')

    # 基础数据生成
    total_contracts = np.random.randint(800, 1200, months)  # 总合同数
    total_premium = np.random.randint(50000000, 100000000, months)  # 总保费收入

    # 再保人角色数据
    lead_re_contracts_pct = np.random.uniform(0.35, 0.55, months)  # 首席再保合同占比
    lead_re_premium_pct = np.random.uniform(0.55, 0.75, months)  # 首席再保保费占比

    # 长短期险数据
    long_term_premium_pct = np.random.uniform(0.65, 0.85, months)  # 长期险保费占比
    short_term_premium_pct = 1 - long_term_premium_pct  # 短期险保费占比

    # 团个险数据
    group_premium_pct = np.random.uniform(0.3, 0.5, months)  # 团险保费占比
    individual_premium_pct = 1 - group_premium_pct  # 个险保费占比

    # 首年期缴/趸缴数据
    first_year_premium_pct = np.random.uniform(0.25, 0.45, months)  # 首年期缴保费占比
    single_premium_pct = 1 - first_year_premium_pct  # 趸缴保费占比

    # 资产和预估数据
    asset_increment = np.random.randint(10000000, 30000000, months)  # 资产增量
    premium_forecast = total_premium * np.random.uniform(0.9, 1.1, months)  # 保费预估值

    # 创建DataFrame
    df = pd.DataFrame({
        'date': dates,
        'total_contracts': total_contracts,
        'total_premium': total_premium,
        'lead_re_contracts_pct': lead_re_contracts_pct,
        'lead_re_premium_pct': lead_re_premium_pct,
        'long_term_premium_pct': long_term_premium_pct,
        'short_term_premium_pct': short_term_premium_pct,
        'group_premium_pct': group_premium_pct,
        'individual_premium_pct': individual_premium_pct,
        'first_year_premium_pct': first_year_premium_pct,
        'single_premium_pct': single_premium_pct,
        'asset_increment': asset_increment,
        'premium_forecast': premium_forecast
    })

    # 计算具体数值
    df['lead_re_contracts'] = (df['total_contracts'] * df['lead_re_contracts_pct']).astype(int)
    df['non_lead_re_contracts'] = df['total_contracts'] - df['lead_re_contracts']
    df['lead_re_premium'] = df['total_premium'] * df['lead_re_premium_pct']
    df['non_lead_re_premium'] = df['total_premium'] - df['lead_re_premium']
    df['long_term_premium'] = df['total_premium'] * df['long_term_premium_pct']
    df['short_term_premium'] = df['total_premium'] * df['short_term_premium_pct']
    df['group_premium'] = df['total_premium'] * df['group_premium_pct']
    df['individual_premium'] = df['total_premium'] * df['individual_premium_pct']
    df['first_year_premium'] = df['total_premium'] * df['first_year_premium_pct']
    df['single_premium'] = df['total_premium'] * df['single_premium_pct']

    # 计算增长率
    df['long_term_premium_growth'] = df['long_term_premium'].pct_change() * 100
    df['short_term_premium_growth'] = df['short_term_premium'].pct_change() * 100
    df['total_premium_growth'] = df['total_premium'].pct_change() * 100

    # 计算其他指标
    df['asset_premium_ratio'] = df['asset_increment'] / df['total_premium']  # 资产增量保费比
    df['forecast_diff_rate'] = (df['premium_forecast'] - df['total_premium']) / df['total_premium'] * 100  # 保费预估差异率

    # 确保增长率在合理范围
    df['long_term_premium_growth'] = df['long_term_premium_growth'].clip(-10, 30)
    df['short_term_premium_growth'] = df['short_term_premium_growth'].clip(-15, 40)

    return df


# 加载数据
df = generate_insurance_data(months)

# 显示最新数据概览
latest_data = df.iloc[-1].copy()
previous_data = df.iloc[-2].copy()

# 格式化日期
latest_data['date'] = latest_data['date'].strftime('%Y-%m-%d')
previous_data['date'] = previous_data['date'].strftime('%Y-%m-%d')


# 指标卡片样式
def metric_card(title, value, delta=None, unit="", is_percent=False, color="primary"):
    if is_percent:
        value_str = f"{value:.2f}%"
        if delta is not None:
            delta_str = f"{delta:.2f}%"
    else:
        if value >= 1e6:
            value_str = f"{value / 1e6:.2f}M"
        elif value >= 1e3:
            value_str = f"{value / 1e3:.2f}K"
        else:
            value_str = f"{value}"

        if delta is not None:
            if delta >= 1e6:
                delta_str = f"{delta / 1e6:.2f}M"
            elif delta >= 1e3:
                delta_str = f"{delta / 1e3:.2f}K"
            else:
                delta_str = f"{delta}"

    if delta is not None:
        delta_color = "normal"
        if delta > 0:
            delta_color = "positive"
        elif delta < 0:
            delta_color = "negative"

        st.metric(
            label=title,
            value=value_str,
            delta=delta_str if delta is not None else None,
            delta_color=delta_color
        )
    else:
        st.markdown(f"""
            <div class="metric-card" style="background-color: #f0f2f6; border-radius: 10px; padding: 1rem; margin-bottom: 1rem;">
                <div style="font-size: 0.875rem; color: #6b7280; margin-bottom: 0.25rem;">{title}</div>
                <div style="font-size: 1.5rem; font-weight: bold; color: {'#165DFF' if color == 'primary' else '#333'}">{value_str}</div>
            </div>
        """, unsafe_allow_html=True)


# 主要指标展示
st.header("关键指标概览")
col1, col2, col3 = st.columns(3)
with col1:
    metric_card(
        "首席再保合同占比",
        latest_data['lead_re_contracts_pct'] * 100,
        (latest_data['lead_re_contracts_pct'] - previous_data['lead_re_contracts_pct']) * 100,
        is_percent=True
    )
    metric_card(
        "长期险保费占比",
        latest_data['long_term_premium_pct'] * 100,
        (latest_data['long_term_premium_pct'] - previous_data['long_term_premium_pct']) * 100,
        is_percent=True
    )
    metric_card(
        "团险保费占比",
        latest_data['group_premium_pct'] * 100,
        (latest_data['group_premium_pct'] - previous_data['group_premium_pct']) * 100,
        is_percent=True
    )
with col2:
    metric_card(
        "首席再保保费占比",
        latest_data['lead_re_premium_pct'] * 100,
        (latest_data['lead_re_premium_pct'] - previous_data['lead_re_premium_pct']) * 100,
        is_percent=True
    )
    metric_card(
        "长期险保费增长率",
        latest_data['long_term_premium_growth'],
        latest_data['long_term_premium_growth'] - previous_data['long_term_premium_growth'],
        is_percent=True
    )
    metric_card(
        "首年期缴保费占比",
        latest_data['first_year_premium_pct'] * 100,
        (latest_data['first_year_premium_pct'] - previous_data['first_year_premium_pct']) * 100,
        is_percent=True
    )
with col3:
    metric_card(
        "短期险保费增长率",
        latest_data['short_term_premium_growth'],
        latest_data['short_term_premium_growth'] - previous_data['short_term_premium_growth'],
        is_percent=True
    )
    metric_card(
        "资产增量保费比",
        latest_data['asset_premium_ratio'],
        latest_data['asset_premium_ratio'] - previous_data['asset_premium_ratio'],
        is_percent=True
    )
    metric_card(
        "保费预估差异率",
        latest_data['forecast_diff_rate'],
        latest_data['forecast_diff_rate'] - previous_data['forecast_diff_rate'],
        is_percent=True
    )

# 图表区域
st.header("业务结构分析")

# 再保人角色分析
fig1, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 5))

# 再保人合同占比
labels = ['首席再保人', '非首席再保人']
sizes = [latest_data['lead_re_contracts'], latest_data['non_lead_re_contracts']]
ax1.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=90, colors=['#165DFF', '#6B7280'])
ax1.axis('equal')
ax1.set_title('再保人合同数量占比')

# 再保人保费占比
sizes = [latest_data['lead_re_premium'], latest_data['non_lead_re_premium']]
ax2.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=90, colors=['#165DFF', '#6B7280'])
ax2.axis('equal')
ax2.set_title('再保人保费收入占比')

plt.tight_layout()
st.pyplot(fig1)

# 险种结构分析
fig2, (ax3, ax4) = plt.subplots(1, 2, figsize=(15, 5))

# 长短期险保费占比
labels = ['长期险', '短期险']
sizes = [latest_data['long_term_premium'], latest_data['short_term_premium']]
ax3.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=90, colors=['#3B82F6', '#F97316'])
ax3.axis('equal')
ax3.set_title('长/短期险保费占比')

# 团个险保费占比
labels = ['团险', '个险']
sizes = [latest_data['group_premium'], latest_data['individual_premium']]
ax4.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=90, colors=['#10B981', '#8B5CF6'])
ax4.axis('equal')
ax4.set_title('团/个险保费占比')

plt.tight_layout()
st.pyplot(fig2)

# 首年期缴/趸缴保费占比
fig3, ax5 = plt.subplots(figsize=(7.5, 5))

labels = ['首年期缴', '趸缴']
sizes = [latest_data['first_year_premium'], latest_data['single_premium']]
ax5.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=90, colors=['#EC4899', '#6366F1'])
ax5.axis('equal')
ax5.set_title('首年期缴/趸缴保费占比')

plt.tight_layout()
st.pyplot(fig3)

# 趋势分析
st.header("趋势分析")

# 长短期险保费增长率趋势
fig4, ax6 = plt.subplots(figsize=(15, 5))

ax6.plot(df['date'], df['long_term_premium_growth'], 'b-', label='长期险保费增长率')
ax6.plot(df['date'], df['short_term_premium_growth'], 'r-', label='短期险保费增长率')
ax6.axhline(y=0, color='gray', linestyle='--', alpha=0.5)
ax6.set_title('长/短期险保费增长率趋势')
ax6.set_xlabel('日期')
ax6.set_ylabel('增长率 (%)')
ax6.legend()
ax6.grid(True)

plt.tight_layout()
st.pyplot(fig4)

# 资产增量保费比和保费预估差异率趋势
fig5, (ax7, ax8) = plt.subplots(1, 2, figsize=(15, 5))

# 资产增量保费比趋势
ax7.plot(df['date'], df['asset_premium_ratio'], 'g-')
ax7.set_title('资产增量保费比趋势')
ax7.set_xlabel('日期')
ax7.set_ylabel('比例')
ax7.grid(True)

# 保费预估差异率趋势
ax8.plot(df['date'], df['forecast_diff_rate'], 'm-')
ax8.axhline(y=0, color='gray', linestyle='--', alpha=0.5)
ax8.set_title('保费预估差异率趋势')
ax8.set_xlabel('日期')
ax8.set_ylabel('差异率 (%)')
ax8.grid(True)

plt.tight_layout()
st.pyplot(fig5)

# 数据表格
st.header("详细数据")
df_display = df.copy()
df_display['date'] = df_display['date'].dt.strftime('%Y-%m-%d')

# 格式化百分比列
percent_cols = [
    'lead_re_contracts_pct', 'lead_re_premium_pct',
    'long_term_premium_pct', 'short_term_premium_pct',
    'group_premium_pct', 'individual_premium_pct',
    'first_year_premium_pct', 'single_premium_pct',
    'long_term_premium_growth', 'short_term_premium_growth',
    'total_premium_growth', 'asset_premium_ratio', 'forecast_diff_rate'
]

for col in percent_cols:
    if 'ratio' in col or 'pct' in col:
        df_display[col] = df_display[col].apply(lambda x: f"{x * 100:.2f}%")
    else:
        df_display[col] = df_display[col].apply(lambda x: f"{x:.2f}%")

# 格式化金额列
amount_cols = [
    'total_premium', 'lead_re_premium', 'non_lead_re_premium',
    'long_term_premium', 'short_term_premium', 'group_premium',
    'individual_premium', 'first_year_premium', 'single_premium',
    'asset_increment', 'premium_forecast'
]

for col in amount_cols:
    df_display[col] = df_display[col].apply(lambda x: f"{x / 10000:.2f}万元")

# 重新排序列
display_order = [
    'date', 'total_contracts', 'total_premium', 'total_premium_growth',
    'lead_re_contracts', 'lead_re_contracts_pct', 'non_lead_re_contracts',
    'lead_re_premium', 'lead_re_premium_pct', 'non_lead_re_premium',
    'long_term_premium', 'long_term_premium_pct', 'long_term_premium_growth',
    'short_term_premium', 'short_term_premium_pct', 'short_term_premium_growth',
    'group_premium', 'group_premium_pct', 'individual_premium', 'individual_premium_pct',
    'first_year_premium', 'first_year_premium_pct', 'single_premium', 'single_premium_pct',
    'asset_increment', 'asset_premium_ratio', 'premium_forecast', 'forecast_diff_rate'
]

df_display = df_display[display_order]

# 重命名列
new_names = {
    'date': '日期',
    'total_contracts': '总合同数',
    'total_premium': '总保费收入',
    'total_premium_growth': '总保费增长率',
    'lead_re_contracts': '首席再保合同数',
    'lead_re_contracts_pct': '首席再保合同占比',
    'non_lead_re_contracts': '非首席再保合同数',
    'lead_re_premium': '首席再保保费',
    'lead_re_premium_pct': '首席再保保费占比',
    'non_lead_re_premium': '非首席再保保费',
    'long_term_premium': '长期险保费',
    'long_term_premium_pct': '长期险保费占比',
    'long_term_premium_growth': '长期险保费增长率',
    'short_term_premium': '短期险保费',
    'short_term_premium_pct': '短期险保费占比',
    'short_term_premium_growth': '短期险保费增长率',
    'group_premium': '团险保费',
    'group_premium_pct': '团险保费占比',
    'individual_premium': '个险保费',
    'individual_premium_pct': '个险保费占比',
    'first_year_premium': '首年期缴保费',
    'first_year_premium_pct': '首年期缴保费占比',
    'single_premium': '趸缴保费',
    'single_premium_pct': '趸缴保费占比',
    'asset_increment': '资产增量',
    'asset_premium_ratio': '资产增量保费比',
    'premium_forecast': '保费预估值',
    'forecast_diff_rate': '保费预估差异率'
}

df_display = df_display.rename(columns=new_names)

# 显示表格
st.dataframe(df_display)

# 页脚
st.markdown("""
<style>
footer {
    visibility: hidden;
}
</style>
""", unsafe_allow_html=True)